/******************************************************************************/
/*                                                                            */
/*  Copyright (c) 2009: ngi-central.org                                       */
/*  All rights reserved.                                                      */
/*                                                                            */
/******************************************************************************/


/// \file
/// This file implements the area algorithm.
//!
//! More information about calculation of area can be found at 
//! \ref area_algorithm.

#ifndef __sgl_area_h__
#define __sgl_area_h__

#include <sgl/global_settings.h>
#include <sgl/conditions.h>
#ifndef _USE_MATH_DEFINES
	#define __SGL_DEFINED_USE_MATH_DEFINES__
	#define _USE_MATH_DEFINES
	#include <math.h>
#endif

namespace sgl {


/******************************************************************************/
/*                                                                            */
/* area                                                                       */
/*                                                                            */
/******************************************************************************/

template <
	/// The geometric primitive. 
	typename E>
/// Get the area.
//!
//! This function calculates the area of a geometric primitive.
//!
//! /return The area of the geometric primitive.
inline typename E::value_type area(
	/// The primitive.
	E const& primitive)
{
	E::value_type area = E::value_type();
	error_type_does_not_support_calculation_of_area(); (*) // see below
	return area;
}

// (*) If you get an error in this line, this means that your type does not
//     support area calculation. However, if you think it should support 
//     calculation of area, you should provide an overload of the area 
//     algorithm, which is able to work with your type.

template <
	/// The element type. 
	typename T>
/// Get the area.
//!
//! This function calculates the area of a box. The area of a box is equal to
//! it's width multiplied by it's height.
//!
//! /return The area of the box.
inline T area(
	/// The box.
	sgl::box<2, T> const& p)
{
	T area = p.size().dx() * p.size().dy();
	return area;
}

template <
	/// The element type. 
	typename T>
/// Get the area.
//!
//! This function calculates the area of a circle. The area of a circle is equal
//! to the squared radius multiplied by pi.
//!
//! /return The area of the circle.
inline T area(
	/// The circle.
	sgl::hyper_sphere<2, T> const& p)
{
	T area = p.radius() * p.radius() * M_PI;
	return area;
}

template <
	/// The element type. 
	typename T>
/// Get the area.
//!
//! This function calculates the area of an ellipse. The area of an ellipse is
//! equal to the major radius multiplied by the minor radius multiplied by pi.
//!
//! /return The area of the ellipse.
inline T area(
	/// The ellipse.
	sgl::hyper_ellipsoid<2, T> const& p)
{
	T area = p.radius().dx() * p.radius().dy() * M_PI;
	return area;
}


} // namespace sgl

#ifdef __SGL_DEFINED_USE_MATH_DEFINES__
	#undef _USE_MATH_DEFINES
#endif

#endif // __sgl_area_h__
